Skip to main content

Node SDK

Stoker provides a Node SDK that can be used to work with your app.

The Stoker CLI uses this SDK under the hood.

Installation

npm i @stoker-platform/node-client

initializeStoker

Initialize a Stoker app.

(
modeEnv: "development" | "production",
configFilePath: string,
customizationFilesPath: string,
gcp?: boolean
) => Promise<NodeUtilities>

Parameters

modeEnv: The environment to start the app in.

configFilePath: The path to you global config file. For example: join(process.cwd(), "config", "main.js")

collectionFiles: The path to your collection config files. For example: join(process.cwd(), "config", "collections")

gcp: Set to true if the app will be running in Google Cloud Platform environment, such as a Cloud Function.

Returns

All Node helper functions.

fetchCurrentSchema

(includeComputedFields?: boolean) => Promise<CollectionsSchema>

Retrieve you app's schema. Set includeComputedFields to true to include computed fields.

fetchLastSchema

() => Promise<CollectionsSchema | undefined>

Retrieve you app's previous schema.

addRecord

(
path: string[],
data: Partial<StokerRecord>,
user?: {
password: string
permissions?: StokerPermissions
},
userId?: string,
options?: {
noTwoWay?: boolean
},
context?: any,
id?: string,
) => Promise<StokerRecord>

Parameters

path: The path to the collection for the record i.e. ["Clients"]. If the record will be in a subcollection, the path will look more like ["Clients", "D89X6ZQ1sclE71BfsWmv", "Sites"].

data: The record to save.

user: Optional user credentials, if this collection has auth enabled. Permissions must be provided in this structure:

type StokerPermissions = {
Role?: string
Enabled?: boolean
collections?: {
[collection: string]: {
auth?: boolean
operations: ("Read" | "Create" | "Update" | "Delete")[]
recordOwner?: {
active: boolean
}
recordUser?: {
active: boolean
}
recordProperty?: {
active: boolean
}
restrictEntities?: boolean
individualEntities?: string[]
parentEntities?: string[]
parentPropertyEntities?: Record<string, string[]>
}
}
}

userId: A user to impersonate.

options.noTwoWay: Do not write two-way relations.

context: The context to pass to hooks.

id: Optionally provide a Firestore id for the new record.

Returns

The saved record.

updateRecord

Update a record in the database.

You only need to provide the fields that you want to update.

To delete a field, provide a Firestore delete sentinel

You can transactionally increment or decrement a field value

(
path: string[],
docId: string,
data: Partial<StokerRecord>,
user?: {
operation: "create" | "update" | "delete"
password?: string
permissions?: StokerPermissions
},
userId?: string,
options?: {
noTwoWay?: boolean
},
context?: any,
) => Promise<StokerRecord>

Parameters

path: The path to the collection for the record i.e. ["Clients"]. If the record is in a subcollection, the path will look more like ["Clients", "D89X6ZQ1sclE71BfsWmv", "Sites"].

docId: The id of the record to update.

data: The data to update.

user: Optional user credentials, if this collection has auth enabled. Permissions must be provided in the structure defined in addRecord above. Use operation to specify whether credentials should be added, updated or deleted.

userId: A user to impersonate.

options.noTwoWay: Do not write two-way relations.

context: The context to pass to hooks.

Returns

The updated record.

deleteRecord

(
path: string[],
docId: string,
userId?: string,
options?: {
force?: boolean;
},
context?: any
) => Promise<StokerRecord>

Parameters

path: The path to the collection for the record i.e. ["Clients"]. If the record is in a subcollection, the path will look more like ["Clients", "D89X6ZQ1sclE71BfsWmv", "Sites"].

docId: The id of the record to delete.

userId: A user to impersonate.

options: Force deletion of records in collections with soft-delete enabled.

context: The context to pass to hooks.

Returns

The deleted record.

getOne

Retrieve a record from the database.

(
path: string[],
docId: string,
options?: {
user?: string
relations?: {
fields?: (string | CollectionField)[]
depth: number
}
subcollections?: {
collections?: string[]
depth: number
constraints?: [string, string, unknown][]
limit?: {
number: number
orderByField: string
orderByDirection: "asc" | "desc"
}
}
providedTransaction?: Transaction
noComputedFields?: boolean
noEmbeddingFields?: boolean
}
) => Promise<StokerRecord>

Parameters

path: The path to the collection for the record i.e. ["Clients"]. If the record is in a subcollection, the path will look more like ["Clients", "D89X6ZQ1sclE71BfsWmv", "Sites"].

docId: The id of the record to retrieve.

options.user: A user to impersonate.

options.relations: Include related records. Specify the depth to retrieve relations for. Optionally specify a subset of relation fields to retrieve.

options.subcollections: Include records from the record's subcollections. Specify the depth to retrieve subcollections for. Optionally specify a subset of subcollections to retrieve. Optionally provide Firestore where() query constraints to apply to subcollection queries. Optionally limit the number of results and specify results sorting.

options.providedTransaction: Provide a Firestore transaction to use for the operation.

options.noComputedFields: Exclude computed fields from the record.

options.noEmbeddingFields: Exclude embeddings fields from the record.

Returns

The record.

getSome

Retrieve multiple records from the database.

(
path: string[],
constraints?: [string, string, unknown][],
options?: {
user?: string
relations?: {
fields?: (string | CollectionField)[]
depth: number
}
subcollections?: {
collections?: string[]
depth: number
constraints?: [string, string, unknown][]
limit?: {
number: number
orderByField: string
orderByDirection: "asc" | "desc"
}
}
pagination?: {
number: number
orderByField?: string
orderByDirection?: "asc" | "desc"
startAfter?: Cursor
endBefore?: Cursor
}
transactional?: boolean
providedTransaction?: Transaction
noEmbeddingFields?: boolean
}
) => Promise<{
cursor: Cursor;
pages: number;
docs: StokerRecord[];
}>

Parameters

path: The path to the collection for the records i.e. ["Clients"]. If the records are in a subcollection, the path will look more like ["Clients", "D89X6ZQ1sclE71BfsWmv", "Sites"].

constraints: Provide Firestore where() query constraints to the query.

options.user: A user to impersonate.

options.relations: Include related records. Specify the depth to retrieve relations for. Optionally specify a subset of relation fields to retrieve.

options.subcollections: Include records from the record's subcollections. Specify the depth to retrieve subcollections for. Optionally specify a subset of subcollections to retrieve. Optionally provide Firestore where() query constraints to apply to subcollection queries. Optionally limit the number of results and specify results sorting.

options.pagination: Specify a number of results per page. Optionally enable sorting of results. Optionally provide a cursor object for startAfter or endBefore.

options.transactional: Set to true to include relation and subcollection documents in the main read transaction. Note that there is a limit of 500 read operations per transaction.

options.providedTransaction: Provide a Firestore transaction to use for the operation.

options.noEmbeddingFields: Exclude embeddings fields from the record.

Returns

cursor: A cursor object that can be passed to startAfter or endBefore in options.pagination above.

pages: The number of pages returned.

docs: The results of the query.

sendMail

Send an email out of the system.

(
to: string | string[],
subject: string,
text?: string,
html?: string,
cc?: string | string[],
bcc?: string | string[],
replyTo?: string,
attachments?: {
filename: string;
content: Buffer;
contentType: string;
}[],
from?: string
) => Promise<void>

sendMessage

(to: string, body: string) => Promise<void>

Send an SMS out of the system. The to field must be a phone number starting with +.

convertDataToTimezone

(date: Date) => DateTime<true> | DateTime<false>

Convert a JavaScript date to a Luxon DateTime object in you app's timezone.

convertTimestampToTimezone

(timestamp: Timestamp) => DateTime<true> | DateTime<false>

Convert a Firebase Timestamp to a Luxon DateTime object in your app's timezone.

keepTimezone

(date: Date, timezone: string) => Date

Set a Javascript date object to your app's timezone while keeping the current date and time.

removeTimezone

(date: Date, timezone: string) => Date

Set a Javascript date object to the server's local timezone while keeping the current date and time.

displayDate

(timestamp: Timestamp | FieldValue) => string

Display a Firebase Timestamp in the date format set in src/main.ts.

tryPromise

(configProperty: any, args?: unknown[]) => Promise<any>

A utility to get a Stoker config value. Provide the raw config value to configProperty. If the value is a function or a promise, add arguments to args. Returns a promise with the config value.

getCachedConfigValue

(config: GlobalConfig | CollectionCustomization, pathArray: ConfigPath, args?: unknown[], overwrite?: boolean) => Promise<any>

A utility to get a cached Stoker config value. Provide the config module to config. Provide a path to the config value, for example ["global", "auth", "enableMultiFactorAuth"] or ["collections", COLLECTION_NAME, "admin", "itemsPerPage"]. If the value is a function or a promise, provide an array of arguments to args. Set overwrite to true to ignore the currently cached value and re-generate the cached value.

getSchema

(operation: "create" | "update", collection: CollectionSchema, schema: CollectionsSchema) => ZodObject

Retrieve the Zod schema for a collection. Provide the operation, the collection's schema and the full app schema.

isDeleteSentinel

isDeleteSentinel: (value: any) => any

A helper to determine whether a value is a Firestore delete sentinel.